<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>Implementers' Draft: OAuth Request Body Hash 1.0 Draft 3</title>
<meta http-equiv="Expires" content="Thu, 12 Mar 2009 16:17:37 +0000">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="OAuth Request Body Hash 1.0 Draft 3">
<meta name="generator" content="xml2rfc v1.33 (http://xml.resource.org/)">
<style type='text/css'><!--
        body {
                font-family: verdana, charcoal, helvetica, arial, sans-serif;
                font-size: small; color: #000; background-color: #FFF;
                margin: 2em;
        }
        h1, h2, h3, h4, h5, h6 {
                font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
                font-weight: bold; font-style: normal;
        }
        h1 { color: #900; background-color: transparent; text-align: right; }
        h3 { color: #333; background-color: transparent; }

        td.RFCbug {
                font-size: x-small; text-decoration: none;
                width: 30px; height: 30px; padding-top: 2px;
                text-align: justify; vertical-align: middle;
                background-color: #000;
        }
        td.RFCbug span.RFC {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: bold; color: #666;
        }
        td.RFCbug span.hotText {
                font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: normal; text-align: center; color: #FFF;
        }

        table.TOCbug { width: 30px; height: 15px; }
        td.TOCbug {
                text-align: center; width: 30px; height: 15px;
                color: #FFF; background-color: #900;
        }
        td.TOCbug a {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
                font-weight: bold; font-size: x-small; text-decoration: none;
                color: #FFF; background-color: transparent;
        }

        td.header {
                font-family: arial, helvetica, sans-serif; font-size: x-small;
                vertical-align: top; width: 33%;
                color: #FFF; background-color: #666;
        }
        td.author { font-weight: bold; font-size: x-small; margin-left: 4em; }
        td.author-text { font-size: x-small; }

        /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */
        a.info {
                /* This is the key. */
                position: relative;
                z-index: 24;
                text-decoration: none;
        }
        a.info:hover {
                z-index: 25;
                color: #FFF; background-color: #900;
        }
        a.info span { display: none; }
        a.info:hover span.info {
                /* The span will display just on :hover state. */
                display: block;
                position: absolute;
                font-size: smaller;
                top: 2em; left: -5em; width: 15em;
                padding: 2px; border: 1px solid #333;
                color: #900; background-color: #EEE;
                text-align: left;
        }

        a { font-weight: bold; }
        a:link    { color: #900; background-color: transparent; }
        a:visited { color: #633; background-color: transparent; }
        a:active  { color: #633; background-color: transparent; }

        p { margin-left: 2em; margin-right: 2em; }
        p.copyright { font-size: x-small; }
        p.toc { font-size: small; font-weight: bold; margin-left: 3em; }
        table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; }
        td.toc { font-size: small; font-weight: bold; vertical-align: text-top; }

        ol.text { margin-left: 2em; margin-right: 2em; }
        ul.text { margin-left: 2em; margin-right: 2em; }
        li      { margin-left: 3em; }

        /* RFC-2629 <spanx>s and <artwork>s. */
        em     { font-style: italic; }
        strong { font-weight: bold; }
        dfn    { font-weight: bold; font-style: normal; }
        cite   { font-weight: normal; font-style: normal; }
        tt     { color: #036; }
        tt, pre, pre dfn, pre em, pre cite, pre span {
                font-family: "Courier New", Courier, monospace; font-size: small;
        }
        pre {
                text-align: left; padding: 4px;
                color: #000; background-color: #CCC;
        }
        pre dfn  { color: #900; }
        pre em   { color: #66F; background-color: #FFC; font-weight: normal; }
        pre .key { color: #33C; font-weight: bold; }
        pre .id  { color: #900; }
        pre .str { color: #000; background-color: #CFF; }
        pre .val { color: #066; }
        pre .rep { color: #909; }
        pre .oth { color: #000; background-color: #FCF; }
        pre .err { background-color: #FCC; }

        /* RFC-2629 <texttable>s. */
        table.all, table.full, table.headers, table.none {
                font-size: small; text-align: center; border-width: 2px;
                vertical-align: top; border-collapse: collapse;
        }
        table.all, table.full { border-style: solid; border-color: black; }
        table.headers, table.none { border-style: none; }
        th {
                font-weight: bold; border-color: black;
                border-width: 2px 2px 3px 2px;
        }
        table.all th, table.full th { border-style: solid; }
        table.headers th { border-style: none none solid none; }
        table.none th { border-style: none; }
        table.all td {
                border-style: solid; border-color: #333;
                border-width: 1px 2px;
        }
        table.full td, table.headers td, table.none td { border-style: none; }

        hr { height: 1px; }
        hr.insert {
                width: 80%; border-style: none; border-width: 0;
                color: #CCC; background-color: #CCC;
        }
--></style>
</head>
<body>
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
<tr><td class="header">Implementers' Draft</td><td class="header">B. Eaton</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">Google, Inc</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">March 12, 2009</td></tr>
</table></td></tr></table>
<h1><br />OAuth Request Body Hash 1.0 Draft 3</h1>

<h3>Abstract</h3>

<p>
        The OAuth Core signature workflow guarantees the integrity of the
        HTTP request body only for
        <tt>application/x-www-form-urlencoded</tt>
        content types.  This specification extends the OAuth signature
        to provide an integrity check of the HTTP request body for other
        content types.
      
</p><a name="toc"></a><br /><hr />
<h3>Table of Contents</h3>
<p class="toc">
<a href="#anchor1">1.</a>&nbsp;
Notation and Conventions<br />
<a href="#anchor2">2.</a>&nbsp;
Related Work<br />
<a href="#anchor3">3.</a>&nbsp;
Request Signing and Verification<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor4">3.1.</a>&nbsp;
Consumer/Service Provider Interoperability<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor5">3.2.</a>&nbsp;
When To Include a Body Hash<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor6">3.3.</a>&nbsp;
Hash Algorithm<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor7">3.4.</a>&nbsp;
Calculating the Hash<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor8">3.5.</a>&nbsp;
Transmitting the Hash<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor9">3.6.</a>&nbsp;
Hash Verification<br />
<a href="#anchor10">4.</a>&nbsp;
Example<br />
<a href="#anchor11">5.</a>&nbsp;
Security Considerations<br />
<a href="#rfc.references1">6.</a>&nbsp;
References<br />
<a href="#rfc.authors">&#167;</a>&nbsp;
Author's Address<br />
</p>
<br clear="all" />

<a name="anchor1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.1"></a><h3>1.&nbsp;
Notation and Conventions</h3>

<p>
        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in <a class='info' href='#RFC2119'>[RFC2119]<span> (</span><span class='info'>Bradner, B., &ldquo;Key words for use in RFCs to Indicate Requirement Levels,&rdquo; .</span><span>)</span></a>.
        Domain name examples use <a class='info' href='#RFC2606'>[RFC2606]<span> (</span><span class='info'>Eastlake, D. and A. Panitz, &ldquo;Reserved Top Level DNS Names,&rdquo; .</span><span>)</span></a>.
      
</p>
<p>
        Unless otherwise noted, this specification is written as a direct
        continuation of <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a>, inheriting the definitions and
        guidelines set by it.
      
</p>
<a name="anchor2"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.2"></a><h3>2.&nbsp;
Related Work</h3>

<p>
        The OAuth Core specification <a class='info' href='#OAuth Core 1.0'>[OAuth Core 1.0]<span> (</span><span class='info'>OAuth Core Workgroup, &ldquo;OAuth Core 1.0,&rdquo; .</span><span>)</span></a> provides
        integrity checking only for 
        <tt>application/x-www-form-urlencoded</tt>
        request bodies.  Other types of request bodies are left unsigned.
        An eavesdropper or man-in-the-middle who obtains a signed request URL
        may be able to replay that URL with a different HTTP request body.
        This security risk is unacceptable for some OAuth deployments.
      
</p>
<p>
        Existing practice in the OAuth community <a class='info' href='#OAuth Body Signing'>[OAuth Body Signing]<span> (</span><span class='info'>, &ldquo;Again : signing the body of HTTP POST and HTTP PUT requests,&rdquo; .</span><span>)</span></a>
        attempts to address this security
        concern by adding an HMAC of the request body into the signature workflow.
        This approach does guarantee the
        integrity of the request body, but can create additional security problems
        for some OAuth Consumers because it requires signing a raw, uninterpreted
        byte stream.  OpenSocial request signing
        <a class='info' href='#OpenSocial Request Signing'>[OpenSocial Request Signing]<span> (</span><span class='info'>OpenSocial Foundation, &ldquo;OpenSocial Request Signing,&rdquo; .</span><span>)</span></a> uses OAuth signatures,
        but cannot use raw body signing because the OpenSocial specification requires
        that OpenSocial containers control the value of some of the parameters
        in the OAuth signature base string (such as opensocial_viewer_id), while
        allowing application authors to control the value of other parameters.
        OpenSocial containers cannot provide an oracle that signs raw byte streams
        because doing so would allow application authors to forge requests that
        include false opensocial parameters.
      
</p>
<p>
        This specification attempts to address these limitations by providing
        an integrity check on the request body without requiring that OAuth
        Consumers create a signing oracle.
      
</p>
<a name="anchor3"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3"></a><h3>3.&nbsp;
Request Signing and Verification</h3>

<a name="anchor4"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.1"></a><h3>3.1.&nbsp;
Consumer/Service Provider Interoperability</h3>

<p>
          Signing of non-form-encoded request bodies is not part of the OAuth
          Core specification.  Service providers MAY require signing of
          non-form-encoded request bodies in the manner described in this
          specification.
        
</p>
<p>
          Consumers SHOULD always sign their request bodies according to
          this specification.  
          A Service Provider that only supports the OAuth Core specification
          will be able to verify the signature on the request, but will
          not have the security benefits of the signed request body.
          A Service Provider that also supports the oauth_body_hash parameter
          will be able to verify the integrity of the request body.
        
</p>
<a name="anchor5"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.2"></a><h3>3.2.&nbsp;
When To Include a Body Hash</h3>

<p>
          Not all requests can have a request body.  For example, HTTP GET
          and HEAD requests do not use request bodies.  If a request
          cannot have a body, Consumers SHOULD NOT send a body hash.
        
</p>
<p>
          If a request uses the application/x-www-form-urlencoded content-type,
          body integrity checks are provided by the OAuth Core specification.
          Consumers SHOULD NOT send a body hash on requests that use
          the application/x-www-form-urlencoded content-type.
        
</p>
<p>
          A body hash SHOULD be sent on all other requests.
        
</p>
<a name="anchor6"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.3"></a><h3>3.3.&nbsp;
Hash Algorithm</h3>

<p>
          If the OAuth signature method is HMAC-SHA1 or RSA-SHA1, SHA1
          <a class='info' href='#RFC3174'>[RFC3174]<span> (</span><span class='info'>Eastlake, 3rd, D. and P. Jones, &ldquo;US Secure Hash Algorithm 1 (SHA1),&rdquo; .</span><span>)</span></a> MUST be used as the body hash algorithm.
        
</p>
<p>
          If the OAuth signature method is PLAINTEXT, use of this specification
          provides no security benefit and is NOT RECOMMENDED.
        
</p>
<p>
          Updates to OAuth that specify new signature methods SHOULD
          also specify the hash algorithm used to generate the body hash.
        
</p>
<a name="anchor7"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.4"></a><h3>3.4.&nbsp;
Calculating the Hash</h3>

<p>
          The body hash value is obtained by executing the selected hash
          algorithm over the HTTP Entity Body defined in section 7.2
          of RFC 2616 <a class='info' href='#RFC2616'>[RFC2616]<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a>.
        
</p>
<a name="anchor8"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.5"></a><h3>3.5.&nbsp;
Transmitting the Hash</h3>

<p>
          The body hash value needs to be transmitted to the Service Provider
          for verification.  For transport the body hash value MUST be
          base64-encoded <a class='info' href='#RFC2045'>[RFC2045]<span> (</span><span class='info'>Freed, N. and N. Borenstein, &ldquo;Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies,&rdquo; .</span><span>)</span></a> and sent to the
          service provider as the oauth_body_hash OAuth Protocol Parameter.
          Protocol Parameters are signed as per section 9 "Signing Request" of
          the OAuth Core specification, and transmitted to the Service
          Provider as per section 5 "Parameters" of the OAuth Core
          specification
        
</p>
<a name="anchor9"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3.6"></a><h3>3.6.&nbsp;
Hash Verification</h3>

<p>
          Service Providers verify the integrity of request bodies
          by verifying the OAuth signature as described in the OAuth Core
          specification and also verifying the value of the
          oauth_body_hash OAuth protocol parameter.
        
</p>
<p>
          To verify the oauth_body_hash parameter the Service Provider
          first calculates the body hash as described above.  The Service
          Provider then compares the calculated parameter with the
          value sent by the Consumer.  If the OAuth signature verifies,
          and the body hash sent by the Consumer and the body hash 
          calculated by the Service Provider match, body integrity is
          intact.
        
</p>
<p>
          Service Providers SHOULD base64 decode the oauth_body_hash
          parameter and compare the raw octets of the hash values rather than
          the encoded versions.  This reduces the risk of small differences
          in URL encoding or base64 encoding causing spurious integrity
          check failures.
        
</p>
<a name="anchor10"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4"></a><h3>4.&nbsp;
Example</h3>

<p>
        Sample HTTP request:
        </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
  PUT /resource
  Host: www.example.com
  Content-Type: application/octet-stream
  Content-Length: 12

  Hello World!
</pre></div><p>

      
</p>
<p>
        Signed request with body hash:
        </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
  PUT /resource
  Host: www.example.com
  Authorization: OAuth realm="http%3A%2F%2Fwww.example.com", oauth_body_hash="Lve95gjOVATpfV8EL5X4nxwjKHE%3D", oauth_consumer_key="consumer", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1236874155", oauth_nonce="10288510250934", oauth_version="1.0", oauth_signature="08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D"
  Content-Type: application/octet-stream
  Content-Length: 12

  Hello World!
</pre></div><p>

      
</p>
<p>
        Corresponding Signature Base String:
        </p>
<div style='display: table; width: 0; margin-left: 3em; margin-right: auto'><pre>
  PUT&amp;http%3A%2F%2Fwww.example.com%2Fresource&amp;oauth_body_hash%3DLve95gjOVATpfV8EL5X4nxwjKHE%253D%26oauth_consumer_key%3Dconsumer%26oauth_nonce%3D10369470270925%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1236874236%26oauth_version%3D1.0
</pre></div><p>

      
</p>
<a name="anchor11"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5"></a><h3>5.&nbsp;
Security Considerations</h3>

<p>
        Many factors besides the bytes of the request body can
        influence the interpretation of the body of the HTTP
        request.  For example, a content-type or content-encoding
        header can change the way a server handles an HTTP request.
        This specification does not include an integrity check
        on the HTTP request headers.  OAuth deployments whose
        security could be impacted by an attacker who replays
        an HTTP request with modified request headers SHOULD
        use other mechanisms (such as HTTPS) to protect the confidentiality
        and integrity of the entire HTTP request.
      
</p>
<a name="rfc.references1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>6.&nbsp;References</h3>
<table width="99%" border="0">
<tr><td class="author-text" valign="top"><a name="OAuth Body Signing">[OAuth Body Signing]</a></td>
<td class="author-text">&ldquo;<a href="http://groups.google.com/group/oauth/browse_thread/thread/acd036474649402a/8a07b353faca5cea">Again : signing the body of HTTP POST and HTTP PUT requests</a>.&rdquo;</td></tr>
<tr><td class="author-text" valign="top"><a name="OAuth Core 1.0">[OAuth Core 1.0]</a></td>
<td class="author-text">OAuth Core Workgroup, &ldquo;<a href="http://oauth.net/core/1.0">OAuth Core 1.0</a>.&rdquo;</td></tr>
<tr><td class="author-text" valign="top"><a name="OpenSocial Request Signing">[OpenSocial Request Signing]</a></td>
<td class="author-text">OpenSocial Foundation, &ldquo;<a href="http://www.opensocial.org/Technical-Resources/opensocial-spec-v08/gadgets-reference08#gadgets.io.makeRequest">OpenSocial Request Signing</a>.&rdquo;</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2045">[RFC2045]</a></td>
<td class="author-text">Freed, N. and N. Borenstein, &ldquo;<a href="http://tools.ietf.org/html/rfc2045">Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</a>,&rdquo; RFC&nbsp;2045.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td>
<td class="author-text">Bradner, B., &ldquo;<a href="http://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a>,&rdquo; RFC&nbsp;2119.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2606">[RFC2606]</a></td>
<td class="author-text">Eastlake, D. and A. Panitz, &ldquo;<a href="http://tools.ietf.org/html/rfc2606">Reserved Top Level DNS Names</a>,&rdquo; RFC&nbsp;2606.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2616">[RFC2616]</a></td>
<td class="author-text">Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;<a href="http://tools.ietf.org/html/rfc2616">Hypertext Transfer Protocol -- HTTP/1.1</a>,&rdquo; RFC&nbsp;2616.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3174">[RFC3174]</a></td>
<td class="author-text">Eastlake, 3rd, D. and P. Jones, &ldquo;<a href="http://tools.ietf.org/html/rfc3174">US Secure Hash Algorithm 1 (SHA1)</a>,&rdquo; RFC&nbsp;3174.</td></tr>
</table>

<a name="rfc.authors"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>Author's Address</h3>
<table width="99%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Brian Eaton</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Google, Inc</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:beaton@google.com">beaton@google.com</a></td></tr>
</table>
</body></html>
